import { boot } from "quasar/wrappers";
import axios from "axios";
import { Notify, Dialog } from "quasar";
import { i18n } from "./i18n";
import { useUserStore } from "src/stores/user";

// Be careful when using SSR for cross-request state pollution
// due to creating a Singleton instance here;
// If any client changes this (global) instance, it might be a
// good idea to move this instance creation inside of the
// "export default () => {}" function below (which runs individually
// for each client)
const api = axios.create({
  baseURL: process.env.API,
  timeout: 40000,
  withCredentials: false,
});

export default boot(({ app, router, store }) => {
  const userStore = useUserStore();
  //请求拦截 打上token和Content-Type
  api.interceptors.request.use(
    (request) => {
      const token = userStore.GetToken();
      request.headers = {
        "Content-Type": "application/json;charset=utf-8",
        "Access-Token": token,
      };
      return request;
    },
    (error) => {
      Notify.create({
        type: "negative",
        message: error,
      });
      return Promise.reject(error);
    }
  );

  //响应拦截
  api.interceptors.response.use(
    (response) => {
      // 如果响应包含refreshed-token 说明JWT的ExpiresAt已经过期，但是RefreshAt没有过期，后端自动提供了新的Token，保存进userStore
      if (response.headers["refreshed-token"] && response.data.data.refreshed) {
        userStore.SetToken(response.headers["refreshed-token"]);
        Notify.create({
          type: "positive",
          message:
            i18n.global.t("Refresh") + "Token" + i18n.global.t("Success"),
        });
        return api(response.config);
      }

      const { code } = response.data;
      //如果返回失败
      if (code === 0) {
        //且返回的数据不为空，并有需要重新登录标记
        console.log(response.data);
        if (response.data.data && response.data.data.relogin_needed) {
          Dialog.create({
            title: i18n.global.t("Authentication") + i18n.global.t("Failed"),
            message:
              response.data.message ||
              i18n.global.t("Please") + i18n.global.t("Relogin"),
            persistent: true,
            ok: {
              push: true,
              color: "negative",
              label: i18n.global.t("Relogin"),
            },
          }).onOk(() => {
            userStore.HandleLogout();
            router.push({ name: "login" });
          });
        }
        // 没有重新登录标记，notify出返回的错误信息，如果没有就简单的提示一下操作失败
        else {
          Notify.create({
            type: "negative",
            message:
              response.data.message ||
              i18n.global.t("Operation") + i18n.global.t("Failed"),
          });
          return response.data;
        }
      } else {
        return response.data;
      }
    },
    (error) => {
      // 500的情况
      if (error + "" === "Error: Request failed with status code 500") {
        Dialog.create({
          title: i18n.global.t("Error"),
          message:
            i18n.global.t("Data") +
            i18n.global.t("Exception") +
            "," +
            i18n.global.t("Please") +
            i18n.global.t("Relogin"),
          persistent: true,
          ok: {
            push: true,
            color: "negative",
            label: i18n.global.t("Logout"),
          },
        }).onOk(() => {
          userStore.HandleLogout();
          // store.dispatch('user/HandleLogout')
          router.push({ name: "login" });
        });
      }
      // 超时
      if (error + "" === "Error: timeout of 40000ms exceeded") {
        Notify.create({
          type: "negative",
          message: i18n.global.t("Operation") + i18n.global.t("Timeout"),
        });
      }
      // 网络错误情况，比如后台没有对应的接口
      if (error + "" === "Error: Network Error") {
        router.push({ name: "notFound" });
      } else if (error.response && error.response.status === 404) {
        console.log(
          "请求地址不存在 [" + error.response.request.responseURL + "]"
        );
        Notify.create({
          type: "negative",
          message:
            i18n.global.t("Request") +
            i18n.global.t("Address") +
            i18n.global.t("NotFound") +
            " " +
            error.response.request.responseURL,
        });
      }
      return Promise.reject(error);
    }
  );

  // for use inside Vue files (Options API) through this.$axios and this.$api

  app.config.globalProperties.$axios = axios;
  // ^ ^ ^ this will allow you to use this.$axios (for Vue Options API form)
  //       so you won't necessarily have to import axios in each vue file

  app.config.globalProperties.$api = api;
  // ^ ^ ^ this will allow you to use this.$api (for Vue Options API form)
  //       so you can easily perform requests against your app's API
});

export { api };
